package com.ivr.cm.handler.validate.impl;

import java.util.AbstractMap;
import java.util.List;

import org.apache.log4j.Logger;

import com.ivr.cm.cache.Cacheable;
import com.ivr.cm.dao.ILimitFeeDao;
import com.ivr.cm.data.ValidateData;
import com.ivr.cm.handler.validate.ValidateServiceIF;
import com.ivr.cm.service.StateCode;
import com.ivr.cm.vo.ConfigBusinessVo;
import com.ivr.cm.vo.ConfigRouterVo;
import com.ivr.cm.vo.UserUsedVo;

/**
 * 验证日上限,月上限
 * @author liugeng
 * @date 2015-12-18
 *
 */
public class ValidateLimitFeeImpl implements ValidateServiceIF {
	private static Logger logger = Logger.getLogger(ValidateLimitFeeImpl.class);
	
	private Cacheable configBusinessCache;
	private Cacheable configRouterCache;
	private ILimitFeeDao limitFeeDao;

	@Override
	public int doProcess(ValidateData validateData) {
		/**获得主叫号码*/
		String mobile = validateData.getBaseData().getCalling();
		/**获得业务号码短号码*/
		String sp_code = validateData.getBaseData().getShort_called();
		/**获得业务长号码*/
		String sp_number = validateData.getBaseData().getLong_called();
		logger.info(String.format("[%s][%s][用户总量鉴权]开始", mobile, sp_code));
		/**根据主叫号码和被叫号码获得用户使用量VO*/
		UserUsedVo userUsedVo = limitFeeDao.getUserUsedVo(mobile, sp_code);
		int day_used_minute = 0;
		int month_used_minute = 0;
		int day_used_money = 0;
		int month_used_money = 0;
		int day_used_num = 0;
		if(userUsedVo != null){
			day_used_minute = userUsedVo.getDay_used_minute();
			month_used_minute = userUsedVo.getMonth_used_minute();
			day_used_num = userUsedVo.getDay_used_num();
		}
		
		/**从缓存中获得路由配置信息*/
		AbstractMap<String, ConfigRouterVo> configRouterMap = (AbstractMap<String, ConfigRouterVo>) configRouterCache.getCache();
		ConfigRouterVo configRouterVo = configRouterMap.get(sp_number);
		/**根据用户拨打长号码判断该长号码是否为自消费*/
		int is_self_consum = configRouterVo.getIs_self_consum();
		if(is_self_consum == 1){
			/**自消费长号码*/
			logger.info(String.format("[%s][%s][用户总量鉴权][自消费]", mobile, sp_number));
			
			/**获得针对长号码使用的日金额和月金额*/
			UserUsedVo userUsedConsumVo = limitFeeDao.getUserUsedVoBySpNumber(mobile, sp_number);
			day_used_money = userUsedConsumVo.getDay_used_money();
			month_used_money = userUsedConsumVo.getMonth_used_money();
		}else{
			/**非自消费长号码*/
			logger.info(String.format("[%s][%s][用户总量鉴权][非自消费]", mobile, sp_number));
			
			day_used_money = userUsedVo.getDay_used_money();
			month_used_money = userUsedVo.getMonth_used_money();
		}
		
		/* 因为对客户号码限制，已经隐去号码的末4位，无法在对单一号码进行限制，去除对单一号码的日月限制 */
		
		logger.info(String.format("[%s][%s][日月限制鉴权]开始", mobile, sp_code));
		/**从缓存中获得SP号码的业务配置信息*/
		AbstractMap<String, ConfigBusinessVo> configBusinessMap = (AbstractMap<String, ConfigBusinessVo>) configBusinessCache.getCache();
		ConfigBusinessVo configBusinessVo = configBusinessMap.get(sp_code);
		/**获得单次拨打时长限制*/
		int one_shot_limit = configBusinessVo.getOne_shot_limit();
		/**获得长号码开始秒数*/
		int start_second = configRouterVo.getStart_second();
		/**获得长号码结束秒数*/
		int end_second = configRouterVo.getEnd_second();
		/**获得日限制 - 日使用数量*/
		int day_remain = configBusinessVo.getDay_limit() - day_used_minute;
		/**获得月限制 - 月使用量*/
		int month_remain = configBusinessVo.getMonth_limit() - month_used_minute;
		
		/**日限制未验证通过*/
		if(day_remain <= 0){
			logger.info(String.format("[%s][%s][日月限制鉴权][日限]未通过,已用[%d],配置信息日限[%d]", mobile, sp_code, day_used_minute, configBusinessVo.getDay_limit()));
			validateData.setResult(ValidateData.RESULT_INVALID_NOTIMELEFT);
			validateData.setVoice(ValidateData.VOICE_INVALID_NOTIMELEFT);
			validateData.setTimeRemain(0);
			validateData.setStatecode(StateCode.DAY_LIMIT);
			return ValidateChain.VALIDATE_FINISHED;
		}
		/**月限制未验证通过*/
		if(month_remain <= 0){
			logger.info(String.format("[%s][%s][日月限制鉴权][月限]未通过,已用[%d],配置信息月限[%d]", mobile, sp_code, month_used_minute, configBusinessVo.getMonth_limit()));
			validateData.setResult(ValidateData.RESULT_INVALID_NOTIMELEFT);
			validateData.setVoice(ValidateData.VOICE_INVALID_NOTIMELEFT);
			validateData.setTimeRemain(0);
			validateData.setStatecode(StateCode.MONTH_LIMIT);
			return ValidateChain.VALIDATE_FINISHED;
		}
		
		boolean use_flag = false;
		long mill = System.currentTimeMillis();
		int sj_second = 0;
		if((end_second - start_second) != 0){
			/**根据开始秒数和结束秒数生成两个中间的一个随机数*/
			sj_second = (int)(mill%(end_second - start_second) + start_second);
			use_flag =  true;
			logger.info(String.format("[%s][%s][日月限制鉴权]通过,使用长号码时长限制", 
					mobile, sp_code));
		}else {
			sj_second = (one_shot_limit * 60);
			logger.info(String.format("[%s][%s][日月限制鉴权]通过,使用单次拨打时长限制", 
					mobile, sp_code));
		}
		
		/**选取3个时间中最小的那个，(秒数)*/
		int remain = Math.min(Math.min((day_remain*60), (month_remain*60)), sj_second);
		logger.info(String.format("[%s][%s][日月限制鉴权]通过,通话时长[%d秒],已用日[%d分]月[%d分],配置信息日[%d分]月[%d分]单次[%d分]", 
				mobile, sp_code, remain, day_used_minute, month_used_minute, configBusinessVo.getDay_limit(), configBusinessVo.getMonth_limit(), configBusinessVo.getOne_shot_limit()));
		
		if((remain < sj_second) || !use_flag){
			/**随机生成11-31的随机数*/
			int sj = (int)(mill%20+11);
			remain = (remain - sj);
		}
		
		if (is_self_consum == 1) {
			validateData.setTimeRemain(0);
		}
		else {
			validateData.setTimeRemain(remain);
		}
		
		/**设置结果1限时拨打*/
		validateData.setResult(ValidateData.RESULT_VALID_LIMITED);
		validateData.setVoice("00");
		
		return ValidateChain.VALIDATE_CONTINUE;
	}

	public Cacheable getConfigBusinessCache() {
		return configBusinessCache;
	}
	public void setConfigBusinessCache(Cacheable configBusinessCache) {
		this.configBusinessCache = configBusinessCache;
	}
	public Cacheable getConfigRouterCache() {
		return configRouterCache;
	}

	public void setConfigRouterCache(Cacheable configRouterCache) {
		this.configRouterCache = configRouterCache;
	}

	public ILimitFeeDao getLimitFeeDao() {
		return limitFeeDao;
	}
	public void setLimitFeeDao(ILimitFeeDao limitFeeDao) {
		this.limitFeeDao = limitFeeDao;
	}
}